/**
 * 
 */
package org.framework2.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collection;

/**
 * <p>
 * 克隆工具类
 * </p>
 * @see 
 * @author aohai.li
 * @version FRAMEWORK2, 2010-8-5
 * @since FRAMEWORK2
 */
public class CloneUtils {

	/**
	 * 克隆对象
	 * @param <T>
	 * @param t
	 * @return
	 */
	public static <T extends Serializable> T clone(T t){
		return cloneObject(t);
	}
	
	/**
	 * 克隆容器
	 * @param <E>
	 * @param <C>
	 * @param c
	 * @return
	 */
	public static <E extends Serializable, C extends Collection<E>> C cloneCollection(C c){
		return cloneObject(c);
	}
	
	/**
	 * 基于序列化的方式进行深度克隆。被克隆对象必须实现序列化接口
	 * @param <T>
	 * @param t
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private static <T> T cloneObject(T t){
		ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        ObjectOutputStream oos = null;  
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;  
        try {  
            oos = new ObjectOutputStream(bos);  
            oos.writeObject(t);  
            bis = new ByteArrayInputStream(bos.toByteArray());  
            ois = new ObjectInputStream(bis);  
            return (T)ois.readObject();  
        } catch (IOException e) {  
        	throw new RuntimeException(t + " is not support clone method.");
        } catch (ClassNotFoundException e) {
        	throw new RuntimeException(e);
		} finally{
			if(null != bos){
				try {
					bos.close();
				} catch (IOException e) {}
			}
			if(null != oos){
				try {
					oos.close();
				} catch (IOException e) {}
			}
			if(null != bis){
				try {
					bis.close();
				} catch (IOException e) {}
			}
			if(null != ois){
				try {
					ois.close();
				} catch (IOException e) {}
			}
		}
	}
}
